package com.anjingsi.tools.resttemplate;

import com.alibaba.fastjson.JSONObject;
import com.anjingsi.tools.Result;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.*;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.util.Map;

/**
 * @Author: anyp
 * @Date: 2020/4/20
 * @Description:
 */
@Configuration
public class RestTemplateUtils {

    private static RestTemplate restTemplate = getInstance();

    public static RestTemplate getInstance() {
        if (restTemplate == null) {
            synchronized (RestTemplateUtils.class) {
                if (restTemplate == null) {
                    restTemplate = new RestTemplate();
                    restTemplate.setRequestFactory(crateClientHttpRequestFactory());
                }
            }
        }
        return restTemplate;
    }

    private static ClientHttpRequestFactory crateClientHttpRequestFactory(){
        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
        factory.setReadTimeout(3000);
        factory.setConnectTimeout(2000);
        return factory;
    }

    // ---------------------------------------------------------------------------------------------

    public Result fromPost(String url, Map<String,Object> parameters){
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        return fromPost(url,parameters,headers);
    }

    public Result fromPost(String url, Map<String,Object> parameters, HttpHeaders headers){
        MultiValueMap<String, Object> map= new LinkedMultiValueMap<>();
        for(Map.Entry<String,Object> map1 : parameters.entrySet()){
            if(null == map1.getValue()){
                map.add(map1.getKey(),null);
            }else {
                map.add(map1.getKey(),map1.getValue());
            }
        }

        HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<>(map, headers);
        try{
            ResponseEntity<String> response = restTemplate.postForEntity( url, request ,String.class );
            return Result.ok(response.getBody());
        }catch (Exception e){
            throw new RuntimeException("无响应结果");
        }
    }

    public Result postUploadFile(String url, HttpHeaders headers, Map<String, Object> params, FileSystemResource fileSystemResource){
        HttpEntity<FileSystemResource> httpEntity = new HttpEntity<>(fileSystemResource, headers);
        try{
            ResponseEntity<String> response = restTemplate.postForEntity(url, httpEntity, null, params);
            return Result.ok(response.getBody());
        }catch (Exception e){
            throw new RuntimeException("无响应结果");
        }
    }

    public  <T,E> E postForEntity(String url, T t,Class<E> target){
        HttpHeaders headers = new HttpHeaders();
        //设置类型
        headers.setContentType(MediaType.APPLICATION_JSON);
        return postForEntity(url,t,target,headers);
    }

    public  <T,E> E postForEntity(String url, T t, Class<E> target, HttpHeaders headers){
        HttpEntity formEntity = new HttpEntity<>(JSONObject.toJSON(t), headers);
        try{
            //发送数据方法
            ResponseEntity<E> forEntity = restTemplate.postForEntity(url, formEntity, target);
            return forEntity.getBody();
        }catch (Exception e){
            throw new RuntimeException("出现异常");
        }
    }

    public  <T> T getForEntity(String url, Map<String,String> parameters,Class<T> target){
        HttpHeaders headers = new HttpHeaders();
        MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
        headers.setContentType(type);
        return getForEntity(url,headers,parameters,target);
    }

    public  <T> T getForEntity(String url, Map<String,String> headers,Map<String,String> parameters,Class<T> target){
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setAll(headers);
        return getForEntity(url,headers,parameters,target);
    }

    public  <T> T getForEntity(String url, HttpHeaders headers, Map<String,String> parameters, Class<T> target){
        HttpEntity<Object> formEntity = new HttpEntity<Object>(headers);
        try{
            //发送数据方法
            ResponseEntity<T> responseEntity = restTemplate.exchange(url, HttpMethod.GET, formEntity, target,parameters);
            return responseEntity.getBody();
        }catch (Exception e){
            throw new RuntimeException("出现异常");
        }
    }

    public <T> T header(String url, HttpMethod httpMethod, Map<String,Object> headerMap, Class<T> target){
        return restTemplate.exchange(url, httpMethod,getHttpEntity(headerMap),target).getBody();
    }

    private static HttpEntity getHttpEntity(Map<String,Object> map){
        HttpHeaders headers = new HttpHeaders();
        for(Map.Entry<String,Object> map1 : map.entrySet()){
            headers.add(map1.getKey(),map1.getValue().toString());
        }
        return new HttpEntity(null,headers);
    }
}
